package cn.jinbyte.core.model;

import cn.jinbyte.core.exception.SysError;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import static cn.jinbyte.core.model.ApiCode.*;

/**
 * 统一响应内容对象
 *
 * @param <T> 响应数据内容类型
 */
@Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@NoArgsConstructor
@SuppressWarnings("unused")
public class ApiRet<T> implements Serializable {
    /**
     * 响应码
     */
    private ApiCode code;
    /**
     * 响应提示信息
     */
    private String message;
    /**
     * 响应数据内容
     */
    private T data;
    /**
     * 响应异常标记
     */
    @JsonIgnore
    private Boolean exception;

    public boolean isOk() {
        return code == ApiCode.OK;
    }

    public Map<String, Object> toMap() {
        Map<String, Object> map = new HashMap<>(3);
        map.put("code", getCode());
        map.put("message", getMessage());
        map.put("data", getData());
        return map;
    }

    public ApiRet(ApiCode code, String message, T data) {
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public ApiRet(Throwable e) {
        this.exception = Boolean.TRUE;
        if (e instanceof SysError sysError) {
            this.code = sysError.getCode();
            this.message = sysError.getMessage();
        } else {
            this.code = ERROR;
            this.message = "系统异常，请联系管理员";
        }
    }

    public static ApiRet<Void> ok() {
        return new ApiRet<>(OK, "操作成功", null);
    }

    public static ApiRet<Void> ok(String message) {
        return new ApiRet<>(OK, message, null);
    }

    public static <T> ApiRet<T> data(T data) {
        return new ApiRet<>(OK, "操作成功", data);
    }

    public static <T> ApiRet<T> data(String message, T data) {
        return new ApiRet<>(OK, message, data);
    }

    public static <T> ApiRet<T> data(ApiCode code, String message, T data) {
        return new ApiRet<>(code, message, data);
    }

    public static <T> ApiRet<T> error() {
        return new ApiRet<>(BS_ERROR, "操作失败", null);
    }

    public static <T> ApiRet<T> error(String message) {
        return new ApiRet<>(BS_ERROR, message, null);
    }

    public static <T> ApiRet<T> error(String message, T data) {
        return new ApiRet<>(BS_ERROR, message, data);
    }

    public static <T> ApiRet<T> error(Throwable e) {
        return new ApiRet<>(e);
    }

    public static ApiRet<Void> error(ApiCode code, String message) {
        return new ApiRet<>(code, message, null);
    }


}

